var mysql = require('mysql');
var path = require('path');
var express = require('express');
var uuid = require('node-uuid');
var bodyParser = require('body-parser'); 
var minimist = require('minimist');
var url = require('url'); 
var fs    = require('fs');
var https = require('https');
var http = require('http'); 
var format = require('string-format');
format.extend(String.prototype); 
var request = require('request');
var urlencode = require('urlencode');
const TUtils = require('./utils');


function THHComm() {
    this.cb = function (callback, p0, p1, p2) {
        try {
            if (callback) {
                callback(p0, p1, p2);
            }
        } catch (e) {
            console.log(e)
        }
    };
    this.isNull = function (obj) {
        var flag = (!obj) || (obj==null);
        return flag;
    };
    this.newId = function (splitStr) {
        var sp = splitStr && splitStr != null ? splitStr : "";
        return [(new Date()).getTime().toString(), parseInt(1000 * Math.random()).toString()].join(splitStr);
    };
    this.getDictItems = function (dict) {
        var res = [];
        for (var p in dict) {
            res.push(dict[p]);
        }
        return res;
    };
    this.getDictValue = function (dict, key, defaultValue) {
        var res = (dict && dict != null && dict[key]) ? dict[key] : defaultValue;
        return res;
    };
    this.extend = function ( a , b) {
        try{
            if( a==null || !a){
                a = {};
            }
            if( b && b!=null){
                for( p in b ){
                    a[p] = b[p];
                }
            }
        }
        catch (e) {
            console.log(e);
        }
        return a;
    };
    this.makeDir = function (dirpath) {
        if (!fs.existsSync(dirpath)) {
            var pathtmp;
            dirpath.split("/").forEach(function(dirname) {
                if (pathtmp) {
                    pathtmp = path.join(pathtmp, dirname);
                }
                else {
    　　　　　　　　　 //如果在linux系统中，第一个dirname的值为空，所以赋值为"/"
                    if(dirname){
                        pathtmp = dirname;
                    }else{
                        pathtmp = "/";
                    }
                }
                if (!fs.existsSync(pathtmp)) {
                    if (!fs.mkdirSync(pathtmp)) {
                        return false;
                    }
                }
            });
        }else{
            return true;
        }
        return true;
    }
}

var comm = new THHComm();
var utils = new TUtils();
function THHApi() {
    var me = this;
    this.config = {
        port: 10081,
        keyFn:"",
        certFn:"",
        //keyFn: "E:/app/kmsdev/dev/svr/keys/4195813_wss.hhdata.cn.key",
        //certFn: "E:/app/kmsdev/dev/svr/keys/4195813_wss.hhdata.cn.pem",
        apiRootPath: "api",
        staticPaths: {
            "/": "d:/svr"
        }
    };
    this.objs = {
        app: null,
        server: null
    };
    this.routes = {};
    this.start = function (routes, onStart) {
        try {
            me.routes = routes;
            var apiPath = ("/" + [me.config.apiRootPath, ":ac"].join("/")).replace("//", "/");
            var app = express();
            for (sp in me.config.staticPaths) {
                app.use(sp, express.static(me.config.staticPaths[sp]));
            }
            var urlencodedParser = bodyParser.urlencoded({extended: false});
            app.use(urlencodedParser);
            app.use(bodyParser.json());
            var jsonParser = bodyParser.json();
            app.all(apiPath, jsonParser, function (req, res) {
                var ac = req.params.ac;
                res.header("Access-Control-Allow-Origin", "*");
                res.header("Access-Control-Allow-Headers", "content-type");
                res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
                var ps = comm.extend({}, req.query);
                var result = {
                    ac: ac,
                    ps: ps,
                    error: null,
                    data: null
                };
                var handler = function (respResult) {
                    if (me.routes[respResult.ac]) {
                        me.routes[respResult.ac](respResult, req, res);
                    }
                };
                if (req.method == "POST") {
                    if( req.headers["content-type"] && req.headers["content-type"].indexOf('application/json')>=0 ){
                        ps = comm.extend(ps, req.body);
                        handler(result);
                    }
                    else {
                        req.setEncoding('utf8');
                        req.on('data', function (data) {
                            try {
                                var obj = JSON.parse(data);
                                ps = extend(ps, obj);
                            } catch (ee) {
                                console.log(ee)
                            }
                        });
                        req.on('end', function () {
                            handler(result);
                        });
                    }
                } else if (req.method == "GET") {
                    handler(result);
                }
            });
            var options = {};
            if (me.config.keyFn && me.config.keyFn != null && me.config.keyFn.length > 0) {
                options = {
                    key: fs.readFileSync(me.config.keyFn),
                    cert: fs.readFileSync(me.config.certFn)
                };
            }
            var httpsServer = options.key? https.createServer(options, app):http.createServer(options, app);
            httpsServer.listen(me.config.port, function (err) {
                if (err) {
                    comm.cb(onStart, {error: err});
                } else {
                    me.objs.app = app;
                    me.objs.server = httpsServer;
                    comm.cb(onStart);
                }
            });
        } catch (e) {
            console.log(e);
        }
    }
}


function THH() {
    var me = this;
    this.apiServer = new THHApi(); 
}

var hh = new THH();
var setApi = function(){
    var jsonParser = bodyParser.json();
    hh.apiServer.objs.app.all("/acQuery/:ac", jsonParser, function (req, resp) {
        try{
            var ac = req.params.ac;
            resp.header("Access-Control-Allow-Origin", "*");
            resp.header("Access-Control-Allow-Headers", "content-type");
            resp.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
            var ps = comm.extend({}, req.query);
            var result = {
                ac: ac,
                ps: ps,
                error: null,
                data: null
            };
            var handler = function (respResult) {
                var sqlFn = respResult.ac;
                sqlFn = [__dirname,"sqls", sqlFn].join("/");
                sqlFn += sqlFn.indexOf(".txt")>0?"":".txt";
                if( fs.existsSync(sqlFn)){
                    var sql = fs.readFileSync(sqlFn,'utf-8');
                    for( p in respResult.ps ){
                        var k = "{"+p+"}";
                        var v = respResult.ps[p];
                        sql = sql.replace(k,v);
                    }
                    utils.queryMs(sql, function(erDB , resDB){
                        respResult.error = "db error."+sql;
                        respResult.data = resDB;
                        resp.send(JSON.stringify(respResult));
                    });
                } 
                else{
                    respResult.error = "key is error:"+ respResult.ac;
                    resp.send(JSON.stringify(respResult));
                }
            };
            if (req.method == "POST") {
                if( req.headers["content-type"].indexOf('application/json')>=0 ){
                    ps = comm.extend(ps, req.body);
                    handler(result);
                }
                else {
                    req.setEncoding('utf8');
                    req.on('data', function (data) {
                        try {
                            var obj = JSON.parse(data);
                            ps = extend(ps, obj);
                        } catch (ee) {
                            console.log(ee)
                        }
                    });
                    req.on('end', function () {
                        handler(result);
                    });
                }
            } else if (req.method == "GET") {
                handler(result);
            }
        }
        catch(erApi){
            console.log(erApi);
        }
    });
}

var routes ={
    "hello":function (result , request , response) {
        result.data ="hello";
        response.send(JSON.stringify(result));
    },
    "real":function (result , request , response) {
        utils.getReals( function(resData , resDict){
            result.data=[];
            if( resData && resData!=null && resData.length>0){
                resData.forEach(function(item){ 
                    var info ={
                        dCode: item.code,
                        dId: item.enId,
                        pm10:item.pm10,
                        pm10Time:item.pm10Time,
                        pm25:item.pm25,
                        pm25Time:item.pm25Time,
                        tsp:item.tsp,
                        tspTime:item.tspTime
                    }
                    result.data.push(info);
                });
                response.send(JSON.stringify(result));
            }
            else{
                response.send(JSON.stringify(result));
            }
        }) 
    },
    "acGetAll24":function (result , request , response) {
        try{
            var start = result.ps.start;
            var end = result.ps.end ;
            var sql = "select * from dbo.apiFun_acGetAll24('"+start+"','"+end+"')";
            utils.queryMs(sql , function(erRes, resData){   
                result.error = erRes ;       
                if( resData){
                    result.data = resData.recordset ;    
                }
                response.send(JSON.stringify(result));
            })
        }
        catch(er){
            console.log(er);
            response.send(JSON.stringify(result));
        }
    },
    "last24":function (result , request , response) {
        try{
            var code = result.ps.code; 
            var sql = "select * from dbo.apiFun_last24('"+code+"')";
            utils.queryMs(sql , function( erRes , resData){
                result.error = erRes ;       
                if( resData){
                    result.data = resData.recordset ;    
                }   
                response.send(JSON.stringify(result));
            })
        }
        catch(er){
            console.log(er);
            response.send(JSON.stringify(result));
        }
    },
    "h24":function (result , request , response) {
        try{
            var code = result.ps.code; 
            var start = result.ps.start; 
            var end = result.ps.end; 
            var sql = "select * from dbo.apiFun_h24('"+code+"','"+start+"','"+end+"')";
            utils.queryMs(sql , function( erRes , resData){
                result.error = erRes ;    
                if( resData){
                    result.data = resData.recordset ;    
                }
                response.send(JSON.stringify(result));
            })
        }
        catch(er){
            console.log(er);
            response.send(JSON.stringify(result));
        }
    } ,
    "acMonthAqi":function (result , request , response) {
        try{
            var start = result.ps.start; 
            var end = result.ps.end; 
            var sql = "select convert(varchar(7),F_Day) as month , max(aqi) as maxAqi from V_Aqi_Day where F_Day>='"+start+"' and F_Day<'"+end+"' group by convert(varchar(7),F_Day) ";
            utils.queryMs(sql , function( erRes , resData){
                result.error = erRes ;       
                if( resData){
                    result.data = resData.recordset ;    
                }   
                response.send(JSON.stringify(result));
            })
        }
        catch(er){
            console.log(er);
            response.send(JSON.stringify(result));
        }
    }  ,
    "acGetEvaluateDay":function (result , request , response) {
        try{ 
            var start = result.ps.start; 
            var end = result.ps.end; 
            var sql = "select * from dbo.apiFun_acGetEvaluate('d','"+start+"','"+end+"')";
            utils.queryMs(sql , function( erRes , resData){
                result.error = erRes ;    
                if( resData){
                    result.data = resData.recordset ;    
                }
                response.send(JSON.stringify(result));
            })
        }
        catch(er){
            console.log(er);
            response.send(JSON.stringify(result));
        }
    }  ,
    "acGetEvaluateWeek":function (result , request , response) {
        try{ 
            var start = result.ps.start; 
            var end = result.ps.end; 
            var sql = "select * from dbo.apiFun_acGetEvaluate('w','"+start+"','"+end+"')";
            utils.queryMs(sql , function( erRes , resData){
                result.error = erRes ;    
                if( resData){
                    result.data = resData.recordset ;    
                }
                response.send(JSON.stringify(result));
            })
        }
        catch(er){
            console.log(er);
            response.send(JSON.stringify(result));
        }
    }  ,
    "acGetEvaluateMonth":function (result , request , response) {
        try{ 
            var start = result.ps.start; 
            var end = result.ps.end; 
            var sql = "select * from dbo.apiFun_acGetEvaluate('m','"+start+"','"+end+"')";
            utils.queryMs(sql , function( erRes , resData){
                result.error = erRes ;    
                if( resData){
                    result.data = resData.recordset ;    
                }
                response.send(JSON.stringify(result));
            })
        }
        catch(er){
            console.log(er);
            response.send(JSON.stringify(result));
        }
    }   ,
    "acGetEvaluateAllWeek":function (result , request , response) {
        try{ 
            var start = result.ps.start; 
            var end = result.ps.end; 
            var sql = "select * from dbo.acGetEvaluateAll( '"+start+"','"+end+"')";
            utils.queryMs(sql , function( erRes , resData){
                result.error = erRes ;    
                if( resData){
                    result.data = resData.recordset ;    
                }
                response.send(JSON.stringify(result));
            })
        }
        catch(er){
            console.log(er);
            response.send(JSON.stringify(result));
        }
    }   ,
    "srchis":function (result , request , response) {
        try{ 
            var code = result.ps.code; 
            var start = result.ps.start; 
            var end = result.ps.end; 
            var sql = "select * from dbo.apiFun_srchis('"+code+"', '"+start+"','"+end+"')";
            utils.queryMs(sql , function( erRes , resData){
                result.error = erRes ;    
                if( resData){
                    result.data = resData.recordset ;    
                }
                response.send(JSON.stringify(result));
            })
            /*
            var code = result.ps.code; 
            var start = result.ps.start; 
            var end = result.ps.end; 
            var sql = "select * from T_Real  where code='"+code+"'  and time>='"+start+"' and time<'"+end+"'  limit 10";
            utils.queryDB(sql , function( resData){
                //result.error = erRes ;    
                if( resData){
                    result.data = resData ;    
                }
                response.send(JSON.stringify(result));
            })
            */
        }
        catch(er){
            console.log(er);
            response.send(JSON.stringify(result));
        }
    }  ,
    "acGetRealAqi":function (result , request , response) {
        try{  
            var sql = "select * from dbo.apiFun_acGetRealAqi( )";
            utils.queryMs(sql , function( erRes , resData){
                result.error = erRes ;    
                if( resData){
                    result.data =[];
                    resData.recordset.forEach(function(item){
                        var info = {
                            dCode: item.F_Code,
                            first:{
                                aqi:item.aqi,
                                k:item.dk,
                                v:item[item.dk]
                            },
                            items:{
                                pm10:{
                                    c:item.pm10,
                                    i:item.pm10Iqi
                                },
                                pm25:{
                                    c:item.pm25,
                                    i:item.pm25Iqi
                                }
                            }

                        };
                        result.data.push(info);
                    }) ;    
                }
                response.send(JSON.stringify(result));
            })
        }
        catch(er){
            console.log(er);
            response.send(JSON.stringify(result));
        }
    }  ,
    "acGetRealAqi_Hour":function (result , request , response) {
        try{  
            var vdate = result.ps.date; 
            var sql = "select * from dbo.apiFun_acGetRealAqi_Hour('"+vdate+"')";
            utils.queryMs(sql , function( erRes , resData){
                result.error = erRes ;    
                if( resData){
                    result.data =[];
                    resData.recordset.forEach(function(item){
                        var info = {
                            dCode: item.F_Code,
                            first:{
                                aqi:item.aqi,
                                k:item.dk,
                                v:item[item.dk]
                            },
                            items:{
                                pm10:{
                                    c:item.pm10,
                                    i:item.pm10Iqi
                                },
                                pm25:{
                                    c:item.pm25,
                                    i:item.pm25Iqi
                                }
                            }

                        };
                        result.data.push(info);
                    }) ;    
                }
                response.send(JSON.stringify(result));
            })
        }
        catch(er){
            console.log(er);
            response.send(JSON.stringify(result));
        }
    }    ,
    "acGetStatic":function (result , request , response) {
        try{ 
            var flag = result.ps.flag; 
            var code = result.ps.code; 
            var start = result.ps.start; 
            var end = result.ps.end; 
            var sql = "select * from dbo.apiFun_acEvaluate('"+flag+"', '"+start+"','"+end+"')";
            if( !code ||  code ==null || code == ""  || code=='*'){
                code = "*";
            }
            if( code !='*'){
                sql += "where F_Code ='"+code+"'";
            }
            utils.queryMs(sql , function( erRes , resData){
                result.error = erRes ;    
                if( resData){
                    result.data = resData.recordset ;    
                }
                response.send(JSON.stringify(result));
            })
        }
        catch(er){
            console.log(er);
            response.send(JSON.stringify(result));
        }
    }  
}
hh.apiServer.start(routes, function () {
    setApi();
    console.log('start web api');
})






